package priv.stones.controller.administrate.shiro;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import priv.stones.entity.SysAdmin;
import priv.stones.entity.SysMenu;
import priv.stones.service.SysAdminService;
import priv.stones.service.SysMenuService;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @Author: Stones
 * @Description:
 * @Date: 2017/10/10 15:27
 */
public class ShiroRealm extends AuthorizingRealm {

    @Autowired
    private SysAdminService sysAdminService;
    @Autowired
    private SysMenuService sysMenuService;

    /**
     * 授权
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SysAdmin sysAdmin = (SysAdmin) principalCollection.getPrimaryPrincipal();
        //拥有的菜单
        List<SysMenu> menuList;
        if (sysAdmin.getName().equals(ShiroUtils.SuperAdmin)) {
            menuList = sysMenuService.selectList(new EntityWrapper<SysMenu>()
                    .eq("status", 1)
                    .orderBy("sort", true));
        } else {
            menuList = sysAdminService.selectOwnMenus(sysAdmin.getId());
        }
        //用户权限列表
        Set<String> permsSet = new HashSet<>();
        for (SysMenu menu : menuList) {
            if (StringUtils.isBlank(menu.getPrivilegemark())) {
                continue;
            }
            permsSet.addAll(Arrays.asList(menu.getPrivilegemark().trim().split(",")));
        }
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setStringPermissions(permsSet);
        return info;
    }

    /**
     * 验证
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        SysAdmin user = sysAdminService.selectOne(new EntityWrapper<SysAdmin>().eq("name", token.getUsername()));
        if (user == null) {
            throw new UnknownAccountException();
        }
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getLoginpwd(), ByteSource.Util.bytes(user.getLoginsalt()), getName());
        return info;
    }

    @Override
    public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
        HashedCredentialsMatcher shaCredentialsMatcher = new HashedCredentialsMatcher();
        shaCredentialsMatcher.setHashAlgorithmName(ShiroUtils.hashAlgorithmName);
        shaCredentialsMatcher.setHashIterations(ShiroUtils.hashIterations);
        super.setCredentialsMatcher(shaCredentialsMatcher);
    }

}
